/**
 * 
 */
package at.fhj.ase.data;

import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * ASE10 - SS2011 
 * Project work Client Architecture and Design
 *  
 * @author Henning Diepold
 * @author Dieter Steiner
 */

public class Customer {
	
	//private final Pattern EMAIL_PATTERN = Pattern.compile("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?");
	private final Pattern EMAIL_PATTERN = Pattern.compile("^[a-zA-Z0-9!#$%&'.*+/=?^_`{|}~-]+@[a-zA_Z0-9!#$%&'*+/=?^_`{|}~-]+\\.[a-zA-Z]{2,3}$");
	//private final Pattern NAME_PATTERN = Pattern.compile("[a-zA-Z0-9_-\\.^']");
	private final Pattern NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9 -\\.^'_]+$");
	private final int MIN_USERNAME_LENGTH = 4;
	private final int MAX_USERNAME_LENGTH = 45;
	private final int MAX_FIRSTNAME_LENGTH = 45;
	private final int MAX_LASTNAME_LENGTH = 45;
	private final int MAX_EMAIL_LENGTH = 45;
	private final int MAX_LOCATION_LENGTH = 45;
	private final int MAX_STREET_LENGTH = 45;
	private final int MAX_COUNTRY_LENGTH = 45;
	
	private int id;
	private String firstname;
	private String lastname;
	private String username;
	private String email;
	private int postcode;
	private String location;
	private String street;
	private String country;
	private Collection <Account> accounts;
	
	public Customer(){
	}

	public Customer(int id, String firstname, String lastname, String username, String email, int postcode, String location, String street, String country) {
		setId(id);
		setFirstname(firstname);
		setLastname(lastname);
		setUsername(username);
		setEmail(email);
		setPostcode(postcode);
		setLocation(location);
		setStreet(street);
		setCountry(country);
	}
	
	/**
	 * @return the id
	 */
	public int getId() {
		return id;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(int id) {
		if((Integer)id == null) {
			throw new IllegalArgumentException("id: not null!");
		}
		else if(id < 0) {
			throw new IllegalArgumentException("id: not < 0");
		}
		else {
			this.id = id;
		}
	}

	/**
	 * @return the firstname
	 */
	public String getFirstname() {
		return firstname;
	}

	/**
	 * @param firstname the firstname to set
	 */
	public void setFirstname(String firstname) {
		if(null == firstname) {
			throw new NullPointerException("firstname: not null!");
		}
		else if("" == firstname) {
			throw new IllegalArgumentException("firstname: not empty!");
		}
		else if(firstname.length() > MAX_FIRSTNAME_LENGTH) {
			throw new IllegalArgumentException("firstname: length!");
		}
		else if(!checkNamePattern(firstname)) {
			throw new IllegalArgumentException("firstname: forbidden characters!");
		}
		else{
			this.firstname = firstname;
		}
	}

	/**
	 * @return the lastname
	 */
	public String getLastname() {
		return lastname;
	}

	/**
	 * @param lastname the lastname to set
	 */
	public void setLastname(String lastname) {
		if(null == lastname) {
			throw new NullPointerException("lastname: not null!");
		}
		else if("" == lastname) {
			throw new IllegalArgumentException("lasstname: not empty!");
		}
		else if(lastname.length() > MAX_LASTNAME_LENGTH) {
			throw new IllegalArgumentException("lastname: length!");
		}
		else if(!checkNamePattern(lastname)) {
			throw new IllegalArgumentException("lastname: forbidden characters!");
		}
		else{
			this.lastname = lastname;
		}
	}

	/**
	 * @return the username
	 */
	public String getUsername() {
		return username;
	}

	/**
	 * @param username the username to set
	 */
	public void setUsername(String username) {
		if(null == username) {
			throw new NullPointerException("username: not null!");
		}
		else if(username == "") {
			throw new IllegalArgumentException("username: not empty!");
		}
		else if(username.length() < MIN_USERNAME_LENGTH || username.length() > MAX_USERNAME_LENGTH) {
			throw new IllegalArgumentException("userame: length!");
		}
		else if(!checkNamePattern(username)) {
			throw new IllegalArgumentException("username: forbidden characters!");
		}
		else{
			this.username = username;
		}
	}

	/**
	 * @return the email
	 */
	public String getEmail() {
		return email;
	}

	/**
	 * @param email the email to set
	 */
	public void setEmail(String email) {
		if(checkEmail(email)) {
			this.email = email;
		}
		else {
			throw new IllegalArgumentException("email: characters not allowed!");
		}
	}

	/**
	 * @return the postcode
	 */
	public int getPostcode() {
		return postcode;
	}

	/**
	 * @return the street
	 */
	public String getStreet() {
		return street;
	}

	/**
	 * @param street the street to set
	 */
	public void setStreet(String street) {
		if(null == street) {
			throw new NullPointerException("street: not null!");
		}
		else if("" == street){
			throw new IllegalArgumentException("street: not empty!");
		}
		else if(street.length() > MAX_STREET_LENGTH) {
			throw new IllegalArgumentException("street: length!");
		}
		else if(!checkNamePattern(street)) {
			throw new IllegalArgumentException("street: forbidden characters!");
		}
		else {
			this.street = street;
		}
	}

	/**
	 * @return the country
	 */
	public String getCountry() {
		return country;
	}

	/**
	 * @param country the country to set
	 */
	public void setCountry(String country) {
		if(null == country) {
			throw new NullPointerException("country: not null!");
		}
		else if("" == country) {
			throw new IllegalArgumentException("country: not empty!");
		}
		else if(country.length() > MAX_COUNTRY_LENGTH) {
			throw new IllegalArgumentException("country: length!");
		}
		else if(!checkNamePattern(country)) {
			throw new IllegalArgumentException("country: forbidden characters!");
		}
		else {
			this.country = country;
		}

	}

	/**
	 * @param postcode the postcode to set
	 */
	public void setPostcode(int postcode) {
		if(null == (Integer)postcode) {
			throw new NullPointerException("postcode: not null!");
		}
		else if(postcode < 0 || postcode > 99999) {
			throw new IllegalArgumentException("postcode: illegal argument!");
		}
		else {
			this.postcode = postcode;
		}
	}

	/**
	 * @return the location
	 */
	public String getLocation() {
		return location;
	}

	/**
	 * @param location the location to set
	 */
	public void setLocation(String location) {
		if(null == location){
			throw new NullPointerException("location: not null!");
		}
		else if("" == location){
			throw new IllegalArgumentException("location: not empty!");
		}
		else if(location.length() > MAX_LOCATION_LENGTH) {
			throw new IllegalArgumentException("location: length!");
		}
		else {
			this.location = location;
		}
	}

	/**
	 * @return the accounts
	 */
	public Collection<Account> getAccounts() {
		// todo: checks
		return accounts;
	}

	/**
	 * @param accounts the accounts to set
	 */
	public void setAccounts(Collection<Account> accounts) {
		this.accounts = accounts;
	}
	
	 /**
     * Check email by means of Regex. 
     * see: http://www.uni-koeln.de/rrzk/kurse/unterlagen/java/javaref/regex/index.htm
     * 
     * @param email
     * @return: TRUE if email is a valid
     */
    private Boolean checkEmail(String email) {
		if(null == email) {
			throw new NullPointerException("email: not null!");
		}
		if("" == email) {
			throw new IllegalArgumentException("email: not empty!");
		}
		if(email.length() > MAX_EMAIL_LENGTH) {
			throw new IllegalArgumentException("email: length!");
		}
		
        Matcher m = EMAIL_PATTERN.matcher(email);
        Boolean b = m.matches();
        return b;
    }
    
    
    /**
     * @param name
     * @return
     */
    private boolean checkNamePattern(String name) {
    	Matcher m = NAME_PATTERN.matcher(name);
    	Boolean b = m.matches();
    	return b;
    }
    
    // housekeeping methods
    
    /**
     * @return object as string
     */
    public String toString() {
    	return getId() + "," + getFirstname() + "," + getLastname() + "," +  getUsername() + "," +  getPostcode() + "," +  getLocation() + "," + getStreet() + "," +  getCountry();
    }
    
    /**
     * 
     * @param customer
     * @return
     */
    public final boolean equals(Customer customer) {
    	if(null == customer) {
    		return false;
    	}
    	if(this == customer) {
    		return true;
    	}
    	if(!customer.getClass().equals(this.getClass())) {
    		return false;
    	}
    	if(customer.getId() == this.getId() && customer.getFirstname() == this.getFirstname() && customer.getLastname() == this.getLastname() && 
    			customer.getUsername() == this.getUsername() && customer.getPostcode() == this.getPostcode() && customer.getLocation() == this.getLocation() &&
    			customer.getStreet() == this.getStreet() && customer.getCountry() == this.getCountry()) {
    		return true;
    	}
    	else {
    		return false;
    	}
    }

    public final int hashCode() {
    	
    	
		return 0;
    	
    }
    
}
